#include "TreeModel.hxx"
//#include "TreeItem.hxx"
#include <QStandardItem>

#include <QStringList>
#include <QFont>
#include "Project.hxx"
#include "Sequence.hxx"
#include "TrackedObject.hxx"

TreeModel::TreeModel(const QString &data, QObject *parent)
    : QStandardItemModel(parent)
{
    _projectItem = 0;

    bool ok = QObject::connect(this, &TreeModel::itemChanged, this, &TreeModel::dataChanged);

    Q_ASSERT(ok);
}

TreeModel::TreeModel(QObject *parent):QStandardItemModel(parent)
{
    _projectItem = 0;

    //bool ok = QObject::connect(this, &TreeModel::itemChanged, this, &TreeModel::dataChanged);

    //Q_ASSERT(ok);
}

TreeModel::~TreeModel()
{
    delete _projectItem;
}

void TreeModel::update(Project* project)
{
    clear();

    if (!project) return;

    QObject::disconnect(this, SIGNAL(itemChanged(QStandardItem*)), this, nullptr);

    QVariant data;
    data.setValue(project);

    _projectItem = new QStandardItem(QString(project->getName().c_str()));
    _projectItem->setIcon(QIcon(":/images/project.png"));
    _projectItem->setData(data);
    appendRow(_projectItem);

    QStandardItem* sequencesItem = new QStandardItem( tr("Sequences") );
    sequencesItem->setIcon(QIcon(":/images/sequences.png"));
    sequencesItem->setFlags(Qt::ItemIsEnabled);
    _projectItem->appendRow(sequencesItem);

    std::vector<Sequence*>* sequences = project->getSequences();

    for (int i = 0; i < sequences->size(); i++)
    {
        Sequence* sequence = sequences->at(i);
        
        QStandardItem* sequenceItem = new QStandardItem( tr(sequence->getName().c_str()));
        sequenceItem->setIcon(QIcon(":/images/sequence.png"));
        sequencesItem->appendRow(sequenceItem);
        sequenceItem->setSelectable(true);

        QVariant data;
        data.setValue(sequence);
        sequenceItem->setData(data);

        if (sequence == project->getActiveSequence())
        {
            QFont font = sequenceItem->font();
            font.setBold(true);
            sequenceItem->setFont(font);
        }

        sequenceItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);


        std::vector<TrackedObject*>* objects = sequence->getTrackedObjects();
        for (int j = 0; j < objects->size(); j++)
        {
            TrackedObject* tobj = objects->at(j);
            QStandardItem* objItem = new QStandardItem(QString("Object %1").arg(tobj->getObjectId()));
            objItem->setIcon(QIcon(":/images/object.png"));
            objItem->setFlags(Qt::ItemIsEnabled);
            sequenceItem->appendRow(objItem);
        }
    }

    QStandardItem* classesItem = new QStandardItem(tr("Classes"));
    classesItem->setIcon(QIcon(":/images/classes.png"));
    classesItem->setFlags(Qt::ItemIsEnabled);
    _projectItem->appendRow(classesItem);

    std::vector<Class*>* classes = project->getClasses();
    for (int i = 0; i < classes->size(); i++)
    {
        Class* cls = classes->at(i);

        QStandardItem* clsItem = new QStandardItem(tr(cls->getName().c_str()));
        clsItem->setIcon(QIcon(":/images/class.png"));
        classesItem->appendRow(clsItem);

        if (cls == project->getActiveClass())
        {
            QFont font = clsItem->font();
            font.setBold(true);
            clsItem->setFont(font);
        }

        QVariant data;
        data.setValue(cls);
        clsItem->setData(data);
    }

    bool ok = QObject::connect(this, &TreeModel::itemChanged, this, &TreeModel::dataChanged);

    Q_ASSERT(ok);
}

void TreeModel::dataChanged(QStandardItem* item)
{
    QVariant data = item->data();
    int usrType = data.userType();
    int seqType = qMetaTypeId<Sequence*>();
    int clsType = qMetaTypeId<Class*>();
    int prjType = qMetaTypeId<Project*>();

    if (usrType == seqType)
    {
        Sequence* sequence = data.value<Sequence*>();
        sequence->setName(item->text().toStdString());
    }
    else if(usrType == clsType)
    {
        Class* cls = data.value<Class*>();
        cls->setName(item->text().toStdString());
    }
    else if (usrType == prjType)
    {
        Project* prj = data.value<Project*>();
        prj->setName(item->text().toStdString());
    }
}